<!DOCTYPE HTML>
<script src="../resources/gc.js"></script>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>

<!--

Accessibility Object Model
Explainer: https://github.com/WICG/aom/blob/master/explainer.md
Spec: https://wicg.github.io/aom/spec/

-->

<div role="listbox" id="listbox" aria-label="container">
    <div role="option" id="option1">Option 1</div>
    <div role="option" id="option2">Option 2</div>
    <div role="option" id="option3">Option 3</div>
</div>

<script>

test(function(t) {
    assert_true(internals.runtimeFlags.accessibilityObjectModelEnabled);
}, "Make sure that Accessibility Object Model is enabled");

promise_test(async function(test) {
    var child_element = document.getElementById("option1");
    var parent_element = document.getElementById("listbox");
    var requestedChildNode = await window.getComputedAccessibleNode(child_element);
    var requestedParentNode = await window.getComputedAccessibleNode(parent_element);

    var computedParent = requestedChildNode.parent;
    assert_false(computedParent === null);
    assert_true(computedParent === requestedParentNode);
    assert_equals(computedParent.name, "container");

    // TODO(meredith): Investigate test case for non-existent parent.
}, "ComputedAccessibleNode.parent.");

promise_test(async function(test) {
    var parent_element = document.getElementById("listbox");
    var requestedParentNode = await window.getComputedAccessibleNode(parent_element);
    var child_element = document.getElementById("option1");
    var requestedChildNode = await window.getComputedAccessibleNode(child_element);

    var computedChild = requestedParentNode.firstChild;
    assert_false(computedChild === null);
    assert_equals(computedChild.name, "Option 1");
    assert_equals(computedChild, requestedChildNode);

    // Check that the option's first child is a text node of same name.
    assert_false(computedChild.firstChild === null);
    assert_equals(computedChild.firstChild.name, "Option 1");

    // Check that a call to non-existent child is an inline textbox of same name.
    assert_false(computedChild.firstChild.firstChild === null);
    assert_equals(computedChild.firstChild.firstChild.name, "Option 1");

    // Check that a call to non-existent child is null.
    assert_equals(computedChild.firstChild.firstChild.firstChild, null);

}, "ComputedAccessibleNode.firstChild.");

promise_test(async function(test) {
    var parent_element = document.getElementById("listbox");
    var requestedParentNode = await window.getComputedAccessibleNode(parent_element);
    var child_element = document.getElementById("option3");
    var requestedChildNode = await window.getComputedAccessibleNode(child_element);

    var computedChild = requestedParentNode.lastChild;
    assert_equals(computedChild, requestedChildNode);
    assert_false(computedChild === null);
    assert_equals(computedChild.name, "Option 3");

    // Check that the option's first child is a text node of same name.
    assert_false(computedChild.firstChild === null);
    assert_equals(computedChild.firstChild.name, "Option 3");

    // Check that a call to non-existent child is an inline textbox of same name.
    assert_false(computedChild.firstChild.firstChild === null);
    assert_equals(computedChild.firstChild.firstChild.name, "Option 3");

    // Check that a call to non-existent child is null.
    assert_equals(computedChild.firstChild.firstChild.firstChild, null);
}, "ComputedAccessibleNode.lastChild.");

promise_test(async function(test) {
    var middleChild = document.getElementById("option2");
    var requestedMiddleChildNode = await window.getComputedAccessibleNode(middleChild);
    var firstBorn = document.getElementById("option1");
    var requestedFirstBorn = await window.getComputedAccessibleNode(firstBorn)

    var computedSibling = requestedMiddleChildNode.previousSibling;
    assert_false(computedSibling === null);
    assert_true(computedSibling === requestedFirstBorn);
    assert_equals(computedSibling.name, "Option 1");

    // Check that a call to non-existent sibling is null.
    assert_equals(computedSibling.previousSibling, null);
}, "ComputedAccessibleNode.previousSibling");

promise_test(async function(test) {
    var middleChild = document.getElementById("option2");
    var requestedMiddleChildNode = await window.getComputedAccessibleNode(middleChild);
    var youngestChild = document.getElementById("option3");
    var requestedYoungestNode = await window.getComputedAccessibleNode(youngestChild)

    var computedSibling = requestedMiddleChildNode.nextSibling;
    assert_false(computedSibling === null);
    assert_true(computedSibling === requestedYoungestNode);
    assert_equals(computedSibling.name, "Option 3");

    // Check that a call to non-existent sibling is null.
    assert_equals(computedSibling.nextSibling, null);
}, "ComputedAccessibleNode.nextSibling");

</script>

